/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.greenrobot.eventbusperf.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.bundle.ElementName;
import ohos.global.resource.Element;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import org.greenrobot.eventbus.ResourceTable;
import org.greenrobot.eventbus.ThreadMode;
import org.greenrobot.eventbusperf.Test;
import org.greenrobot.eventbusperf.TestParams;
import org.greenrobot.eventbusperf.testsubject.PerfTestEventBus;

import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Logger;

import static java.util.logging.Level.INFO;

public class TestSetupSlice extends AbilitySlice {

    @SuppressWarnings("rawtypes")
    static final Class[] TEST_CLASSES_EVENTBUS = {PerfTestEventBus.Post.class,//
            PerfTestEventBus.RegisterOneByOne.class,//
            PerfTestEventBus.RegisterAll.class, //
            PerfTestEventBus.RegisterFirstTime.class};

//    static final Class[] TEST_CLASSES_OTTO = {PerfTestOtto.Post.class,//
//            PerfTestOtto.RegisterOneByOne.class,//
//            PerfTestOtto.RegisterAll.class, //
//            PerfTestOtto.RegisterFirstTime.class};

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_activity_setuptests);
    }

    @Override
    public void onActive() {
        super.onActive();
        Picker spinnerTestToRun = (Picker) findComponentById(ResourceTable.Id_spinnerTestToRun);
        Picker spinnerThread = (Picker) findComponentById(ResourceTable.Id_spinnerThread);
        try {
            Element element = getResourceManager().getElement(ResourceTable.Strarray_spinnerTestsToRun);
            spinnerTestToRun.setDisplayedData(element.getStringArray());

            element = getResourceManager().getElement(ResourceTable.Strarray_spinnerThreadModes);
            spinnerThread.setDisplayedData(element.getStringArray());
        } catch (IOException | NotExistException | WrongTypeException e) {
            Logger.getGlobal().log(INFO, e.toString());
        }
        spinnerTestToRun.setValueChangedListener(new Picker.ValueChangedListener() {
            @Override
            public void onValueChanged(Picker picker, int oldVal, int newVal) {
                int eventsVisibility = newVal == 0 ? Component.VISIBLE : Component.HIDE;
                findComponentById(ResourceTable.Id_relativeLayoutForEvents).setVisibility(eventsVisibility);
                findComponentById(ResourceTable.Id_spinnerThread).setVisibility(eventsVisibility);
            }
        });

        Checkbox checkBoxEventBus = (Checkbox) findComponentById(ResourceTable.Id_checkBoxEventBus);
        checkBoxEventBus.setChecked(true);
        checkBoxEventBus.setCheckedStateChangedListener(new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton absButton, boolean isChecked) {
                checkEventBus();
            }
        });

        Button buttonStart = (Button) findComponentById(ResourceTable.Id_buttonStart);
        buttonStart.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                startClick(component);
            }
        });
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }


    public void checkEventBus() {
        Picker spinnerThread = (Picker) findComponentById(ResourceTable.Id_spinnerThread);
        Checkbox checkBoxEventBus = (Checkbox) findComponentById(ResourceTable.Id_checkBoxEventBus);
        int visibility = checkBoxEventBus.isChecked() ? Component.VISIBLE : Component.HIDE;
        spinnerThread.setVisibility(visibility);
    }

    public void startClick(Component v) {
        TestParams params = new TestParams();
        Picker spinnerThread = (Picker) findComponentById(ResourceTable.Id_spinnerThread);
        String threadModeStr = spinnerThread.getDisplayedData()[spinnerThread.getValue()];
        ThreadMode threadMode = ThreadMode.valueOf(threadModeStr);
        params.setThreadMode(threadMode);

        params.setEventInheritance(((Checkbox) findComponentById(ResourceTable.Id_checkBoxEventBusEventHierarchy)).isChecked());
        params.setIgnoreGeneratedIndex(((Checkbox) findComponentById(ResourceTable.Id_checkBoxEventBusIgnoreGeneratedIndex)).isChecked());

        TextField editTextEvent = (TextField) findComponentById(ResourceTable.Id_editTextEvent);
        params.setEventCount(Integer.parseInt(editTextEvent.getText().toString()));

        TextField editTextSubscriber = (TextField) findComponentById(ResourceTable.Id_editTextSubscribe);
        params.setSubscriberCount(Integer.parseInt(editTextSubscriber.getText().toString()));

        Picker spinnerTestToRun = (Picker) findComponentById(ResourceTable.Id_spinnerTestToRun);
        int testPos = spinnerTestToRun.getValue();
        params.setTestNumber(testPos + 1);
        ArrayList<Class<? extends Test>> testClasses = initTestClasses(testPos);
        params.setTestClasses(testClasses);

        Intent intent = new Intent();
        intent.setElement(new ElementName("", "com.greenrobot.eventbus", "org.greenrobot.eventbusperf.slice.TestRunnerAbility"));
        intent.setParam("params", params);
        present(new TestRunnerSlice(), intent);
    }

    @SuppressWarnings("unchecked")
    private ArrayList<Class<? extends Test>> initTestClasses(int testPos) {
        ArrayList<Class<? extends Test>> testClasses = new ArrayList<Class<? extends Test>>();
        // the attributes are putted in the intent (eventbus, otto, broadcast, local broadcast)
        final Checkbox checkBoxEventBus = (Checkbox) findComponentById(ResourceTable.Id_checkBoxEventBus);
        final Checkbox checkBoxOtto = (Checkbox) findComponentById(ResourceTable.Id_checkBoxOtto);
        final Checkbox checkBoxBroadcast = (Checkbox) findComponentById(ResourceTable.Id_checkBoxBroadcast);
        final Checkbox checkBoxLocalBroadcast = (Checkbox) findComponentById(ResourceTable.Id_checkBoxLocalBroadcast);
        if (checkBoxEventBus.isChecked()) {
            testClasses.add(TEST_CLASSES_EVENTBUS[testPos]);
        }
        return testClasses;
    }
}
